from datetime import datetime, timedelta, timezone
from typing import Any
from fastapi import Request

import jwt
from passlib.context import CryptContext
from app.core.config import settings
from app.core.logger import logger
from hashlib import sha256

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

ALGORITHM = "HS256"

def create_access_token(subject: str | Any, expires_delta: timedelta) -> str:
    expire = datetime.now(timezone.utc) + expires_delta
    to_encode = {"exp": expire, "sub": str(subject)}
    encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

async def get_user_id_from_token(request: Request) -> int:
    """
    从请求头中提取用户ID
    """
    token = request.headers.get("Authorization")
    if not token:
        return None
    try:
        # 移除 "Bearer " 前缀
        token = token.replace("Bearer ", "")
        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[ALGORITHM])
        user_id: str = payload.get("sub")
        return int(user_id)
    except jwt.PyJWTError:
        return None

def verify_password(plain_password: str, hashed_password: str) -> bool:
    sha_password = sha256(plain_password.encode('utf-8')).hexdigest()
    return pwd_context.verify(sha_password, hashed_password)


def get_password_hash(password: str) -> str:
    # 先用 SHA256 将密码哈希成固定长度（32字节）
    # 避免 bcrypt 72字节限制
    sha_str = sha256(password.encode('utf-8')).hexdigest()
    logger.info(f"Password hash attempt for password: {password}")
    logger.info(f"Password byte length: {len(sha_str.encode('utf-8'))} bytes")  # 打印实际字节长度
    return pwd_context.hash(sha_str)
